#include "LanguageSymbols.h"
#include "WllString.h"
#include <memory>
#include <cassert>
#include <sstream>
#include <cstring>
#include <math.h>
#include <CompilerManager.h>
//#include <algorithm>
using namespace std;
using namespace Wll::Util;


//SymbolTypes类实现部分

StringTable SymbolTypes::type_table;


const SymbolTypes SymbolTypes::ANY_TYPE("@ANY_TYPE");   //任意类型
const SymbolTypes SymbolTypes::VOID_TYPE("@VOID_TYPE");		//VOID类型，作为空类型
const SymbolTypes SymbolTypes::VARIABLE_TYPE("@VARIABLE_TYPE");	//文法变量类型
const SymbolTypes SymbolTypes::REMARK_TYPE("@REMARK_TYPE");		//文法标记类型
const SymbolTypes SymbolTypes::CONSTANT_TYPE("@CONSTANT_TYPE");	//文法常量类型
//自動類型轉換的順序是由低向高
const SymbolTypes SymbolTypes::CHAR_TYPE("@CHAR_TYPE");            //单个字符类型
const SymbolTypes SymbolTypes::INTEGER_TYPE("@INTEGER_TYPE");		//整数类型
const SymbolTypes SymbolTypes::LONG_TYPE("@LONG_TYPE");		//长整数类型
const SymbolTypes SymbolTypes::FLOAT_TYPE("@FLOAT_TYPE");		//浮点数类型
const SymbolTypes SymbolTypes::DOUBLE_TYPE("@DOUBLE_TYPE");		//双精度浮点数类型
const SymbolTypes SymbolTypes::STRING_TYPE("@STRING_TYPE");		//字符串类型
const SymbolTypes SymbolTypes::REFERENCE_TYPE("@REFERENCE_TYPE");	//引用類型(指針類型)

const SymbolTypes SymbolTypes::COMPACT_TYPE("@COMPACT_TYPE");		//(同之前的内部打包解包类型)
const SymbolTypes SymbolTypes::S_EXP_TYPE("@S_EXP_TYPE");		//S表达式类型
const SymbolTypes SymbolTypes::LIST_TYPE("@LIST_TYPE");		//数组类型
const SymbolTypes SymbolTypes::MAP_TYPE("@MAP_TYPE");		//字典类型

const SymbolTypes SymbolTypes::USER_DEFINE_TYPE("@USER_DEFINE_TYPE");    //用户自定义类型



SymbolTypes::SymbolTypes(const char* type_name)
{
    type_code = type_table.GetIndexByName(type_name);
}

SymbolTypes::SymbolTypes()
{
    type_code = 1;
}

bool SymbolTypes::operator< (const SymbolTypes& that) const
{
    return this->type_code < that.type_code;
}

bool SymbolTypes::operator== (const SymbolTypes& that) const
{
    return this->type_code == that.type_code;
}

std::string SymbolTypes::ToString() const
{
    return type_table.GetNameByIndex(this->type_code);
}

void SymbolTypes::Load(istream& i)
{
    SymbolTypes::type_table.Load(i);
}

void SymbolTypes::Save(ostream& o)
{
    SymbolTypes::type_table.Save(o);
}

//Symbols类实现部分

StringTable Symbols::variable_table;
StringTable Symbols::remark_table;
StringTable Symbols::value_table;


const Symbols Symbols::VOID;
//支持文法解析
const Symbols Symbols::NULL_SYMBOL(SymbolTypes::REMARK_TYPE,"$NULL");
const Symbols Symbols::END_SYMBOL(SymbolTypes::REMARK_TYPE,"$END");
const Symbols Symbols::ANY_SYMBOL(SymbolTypes::ANY_TYPE, SymbolTypes::ANY_TYPE);
const Symbols Symbols::ANY_VARIABLE(SymbolTypes::ANY_TYPE, SymbolTypes::VARIABLE_TYPE);
const Symbols Symbols::ANY_REMARK(SymbolTypes::ANY_TYPE, SymbolTypes::REMARK_TYPE);
const Symbols Symbols::ANY_CONSTANT(SymbolTypes::ANY_TYPE, SymbolTypes::CONSTANT_TYPE);
const Symbols Symbols::ANY_CHAR(SymbolTypes::ANY_TYPE, SymbolTypes::CHAR_TYPE);
const Symbols Symbols::ANY_INTEGER(SymbolTypes::ANY_TYPE, SymbolTypes::INTEGER_TYPE);
const Symbols Symbols::ANY_LONG(SymbolTypes::ANY_TYPE, SymbolTypes::LONG_TYPE);
const Symbols Symbols::ANY_FLOAT(SymbolTypes::ANY_TYPE, SymbolTypes::FLOAT_TYPE);
const Symbols Symbols::ANY_DOUBLE(SymbolTypes::ANY_TYPE, SymbolTypes::DOUBLE_TYPE);
const Symbols Symbols::ANY_STRING(SymbolTypes::ANY_TYPE, SymbolTypes::STRING_TYPE);		//字符串类型
const Symbols Symbols::ANY_REFERENCE(SymbolTypes::ANY_TYPE, SymbolTypes::REFERENCE_TYPE);    //引用类型

const Symbols Symbols::ANY_COMPACT(SymbolTypes::ANY_TYPE, SymbolTypes::COMPACT_TYPE); ;      //组合类型
const Symbols Symbols::ANY_S_EXP(SymbolTypes::ANY_TYPE, SymbolTypes::S_EXP_TYPE); 		//S表达式类型
const Symbols Symbols::ANY_LIST(SymbolTypes::ANY_TYPE, SymbolTypes::LIST_TYPE); 		//数组类型
const Symbols Symbols::ANY_MAP(SymbolTypes::ANY_TYPE, SymbolTypes::MAP_TYPE); 		//字典类型
//支持WLL0文法自解释
const Symbols Symbols::WLL0(SymbolTypes::REMARK_TYPE, "$WLL0");
const Symbols Symbols::WLL1(SymbolTypes::REMARK_TYPE, "$WLL1");
const Symbols Symbols::WLL2(SymbolTypes::REMARK_TYPE, "$WLL2");
const Symbols Symbols::WLL3(SymbolTypes::REMARK_TYPE, "$WLL3");

const Symbols Symbols::REMARK_TRANSLATION(SymbolTypes::REMARK_TYPE,"$TRANSLATION");
const Symbols Symbols::REMARK_SOURCE_RULE(SymbolTypes::REMARK_TYPE,"$SOURCE_RULE");
const Symbols Symbols::REMARK_DESTINATION_RULE(SymbolTypes::REMARK_TYPE,"$DESTINATION_RULE");
const Symbols Symbols::REMARK_RULE(SymbolTypes::REMARK_TYPE,"$RULE");
const Symbols Symbols::REMARK_ROOT_SYMBOL(SymbolTypes::REMARK_TYPE,"$ROOT_SYMBOL");
const Symbols Symbols::REMARK_EXPRESSION(SymbolTypes::REMARK_TYPE,"$EXPRESSION");
const Symbols Symbols::REMARK_SUB_SYMBOL(SymbolTypes::REMARK_TYPE,"$SUB_SYMBOL");
const Symbols Symbols::REMARK_VARIABLE(SymbolTypes::REMARK_TYPE,"$VARIABLE");
const Symbols Symbols::REMARK_CONSTANT(SymbolTypes::REMARK_TYPE,"$CONSTANT");
const Symbols Symbols::REMARK_REMARK(SymbolTypes::REMARK_TYPE,"$REMARK");

const Symbols Symbols::REMARK_IGNORE(SymbolTypes::REMARK_TYPE,"$IGNORE");
const Symbols Symbols::IGNORE_BEGIN(SymbolTypes::REMARK_TYPE,"$IGNORE_BEGIN");
const Symbols Symbols::IGNORE_END(SymbolTypes::REMARK_TYPE,"$IGNORE_END");
const Symbols Symbols::COMPACT(SymbolTypes::REMARK_TYPE,"$COMPACT");
const Symbols Symbols::COMPACT_BEGIN(SymbolTypes::REMARK_TYPE,"$COMPACT_BEGIN");
const Symbols Symbols::COMPACT_END(SymbolTypes::REMARK_TYPE,"$COMPACT_END");
//支持S表达式求解(WLL1文法自解释)
const Symbols Symbols::EVAL(SymbolTypes::REMARK_TYPE,"$EVAL");
const Symbols Symbols::EXEC(SymbolTypes::REMARK_TYPE,"$EXEC");
const Symbols Symbols::LEFT_QUOTE(SymbolTypes::REMARK_TYPE,"$LEFT_QUOTE");
const Symbols Symbols::RIGHT_QUOTE(SymbolTypes::REMARK_TYPE,"$RIGHT_QUOTE");
const Symbols Symbols::SEPERATOR(SymbolTypes::REMARK_TYPE,"$SEPERATOR");
const Symbols Symbols::LOAD_TRANSLATIONS(SymbolTypes::REMARK_TYPE,"$LOAD_TRANSLATIONS");
const Symbols Symbols::CLEAR_TRANSLATIONS(SymbolTypes::REMARK_TYPE,"$CLEAR_TRANSLATIONS");
const Symbols Symbols::ADD_TRANSLATIONS(SymbolTypes::REMARK_TYPE,"$ADD_TRANSLATIONS");
const Symbols Symbols::CREATE_COMPILER(SymbolTypes::REMARK_TYPE,"$CREATE_COMPILER");

//支持Ｓ表达式求值
const Symbols Symbols::LIST(SymbolTypes::REMARK_TYPE,"$LIST");
const Symbols Symbols::APPEND(SymbolTypes::REMARK_TYPE,"$APPEND");
const Symbols Symbols::CAR(SymbolTypes::REMARK_TYPE,"$CAR");
const Symbols Symbols::CDR(SymbolTypes::REMARK_TYPE,"$CDR");
//控制結構
const Symbols Symbols::COND(SymbolTypes::REMARK_TYPE,"$COND");
const Symbols Symbols::LOOP(SymbolTypes::REMARK_TYPE,"$LOOP");
const Symbols Symbols::CALL(SymbolTypes::REMARK_TYPE,"$CALL");
const Symbols Symbols::FCALL(SymbolTypes::REMARK_TYPE,"$FCALL");

//支持变量存储
const Symbols Symbols::LREF(SymbolTypes::REMARK_TYPE,"$LREF");
const Symbols Symbols::RREF(SymbolTypes::REMARK_TYPE,"$RREF");
const Symbols Symbols::DEF(SymbolTypes::REMARK_TYPE,"$DEF");
const Symbols Symbols::SET(SymbolTypes::REMARK_TYPE,"$SET");
const Symbols Symbols::GET(SymbolTypes::REMARK_TYPE,"$GET");
const Symbols Symbols::PUSH_DATA(SymbolTypes::REMARK_TYPE,"$PUSH_DATA");
const Symbols Symbols::POP_DATA(SymbolTypes::REMARK_TYPE,"$POP_DATA");
const Symbols Symbols::PUSH(SymbolTypes::REMARK_TYPE,"$PUSH");
const Symbols Symbols::POP(SymbolTypes::REMARK_TYPE,"$POP");
//支持数据结构
const Symbols Symbols::MAP(SymbolTypes::REMARK_TYPE,"$MAP");
const Symbols Symbols::ARRAY(SymbolTypes::REMARK_TYPE,"$ARRAY");

const Symbols Symbols::CHAR(SymbolTypes::REMARK_TYPE,"$CHAR");
const Symbols Symbols::INTEGER(SymbolTypes::REMARK_TYPE,"$INTEGER");
const Symbols Symbols::LONG(SymbolTypes::REMARK_TYPE,"$LONG");
const Symbols Symbols::FLOAT(SymbolTypes::REMARK_TYPE,"$FLOAT");
const Symbols Symbols::DOUBLE(SymbolTypes::REMARK_TYPE,"$DOUBLE");
const Symbols Symbols::STRING(SymbolTypes::REMARK_TYPE,"$STRING");

const Symbols Symbols::SYMBOL(SymbolTypes::REMARK_TYPE,"$SYMBOL");
const Symbols Symbols::CAST(SymbolTypes::REMARK_TYPE,"$CAST");
//支持运算控制
const Symbols Symbols::ADD(SymbolTypes::REMARK_TYPE,"$ADD");
const Symbols Symbols::SUB(SymbolTypes::REMARK_TYPE,"$SUB");
const Symbols Symbols::MUL(SymbolTypes::REMARK_TYPE,"$MUL");
const Symbols Symbols::DIV(SymbolTypes::REMARK_TYPE,"$DIV");
const Symbols Symbols::TRUE(SymbolTypes::REMARK_TYPE,"$TRUE");
const Symbols Symbols::FALSE(SymbolTypes::REMARK_TYPE,"$FALSE");
const Symbols Symbols::EQ(SymbolTypes::REMARK_TYPE,"$EQ");
const Symbols Symbols::SAME(SymbolTypes::REMARK_TYPE,"$SAME");
const Symbols Symbols::LT(SymbolTypes::REMARK_TYPE,"$LT");
const Symbols Symbols::AND(SymbolTypes::REMARK_TYPE,"$AND");
const Symbols Symbols::OR(SymbolTypes::REMARK_TYPE,"$OR");
const Symbols Symbols::NOT(SymbolTypes::REMARK_TYPE,"$NOT");

//其他命令
const Symbols Symbols::SUB_STR(SymbolTypes::REMARK_TYPE,"$SUB_STR");
const Symbols Symbols::SHELL(SymbolTypes::REMARK_TYPE,"$SHELL");
const Symbols Symbols::CAT(SymbolTypes::REMARK_TYPE,"$CAT");
const Symbols Symbols::IDLE(SymbolTypes::REMARK_TYPE,"$IDLE");


void Symbols::Init()
{
	this->type = SymbolTypes::VOID_TYPE;
	this->value = 0;
	
	this->s = NULL;
	this->list = NULL;
	this->m = NULL;
	this->reference = NULL;
}

void Symbols::Destroy()
{
	if(this->type == SymbolTypes::COMPACT_TYPE || this->type == SymbolTypes::S_EXP_TYPE || this->type == SymbolTypes::LIST_TYPE)
    {
        if (this->list != NULL)
        {
            //(*this->list).reset();
            delete this->list;
            this->list = NULL;
        }
    }
	else if (this->type == SymbolTypes::MAP_TYPE)
    {
        if (this->m != NULL)
        {
            //(*this->m).reset();
            delete this->m;
            this->m = NULL;
        }
    }
	else if (this->type == SymbolTypes::STRING_TYPE)
    {
        if (this->s != NULL)
        {
            delete this->s;
            this->s = NULL;
        }
    }
	
	this->Init();
}

void Symbols::Copy(const Symbols& that)
{
	this->type = that.type;

    if (that.type == SymbolTypes::CHAR_TYPE)
    {
        this->c = that.c;
    }
    else if (that.type == SymbolTypes::INTEGER_TYPE)
    {
        this->i = that.i;
    }
    else if (that.type == SymbolTypes::LONG_TYPE)
    {
        this->l = that.l;
    }
    else if (that.type == SymbolTypes::FLOAT_TYPE)
    {
        this->f = that.f;
    }
    else if (that.type == SymbolTypes::DOUBLE_TYPE)
    {
        this->d = that.d;
    }
	else if (that.type == SymbolTypes::COMPACT_TYPE || that.type == SymbolTypes::S_EXP_TYPE || that.type == SymbolTypes::LIST_TYPE)
    {
        this->list = new shared_ptr< vector<Symbols> >(*that.list);
    }
	else if (that.type == SymbolTypes::MAP_TYPE)
    {
        this->m = new shared_ptr<map<string, Symbols> >(*that.m);
    }
	else if (that.type == SymbolTypes::STRING_TYPE)
    {
        this->s = new shared_ptr<string>(*that.s);
    }
	else if (that.type == SymbolTypes::REFERENCE_TYPE)
    {
        this->reference = that.reference;
    }
	else
    {
		this->value = that.value;
	}
}

Symbols::Symbols()
{
	this->type = SymbolTypes::VOID_TYPE;
	this->value = 0;
	
	this->s = NULL;
	this->list = NULL;
	this->m = NULL;
	this->reference = NULL;
}

Symbols::Symbols(const Symbols& that)
{
	this->Copy(that);
}

Symbols& Symbols::operator= (const Symbols& that)
{
	if (this == &that) return *this;
	this->Destroy();
	this->Copy(that);
	return *this;
}

Symbols::~Symbols()
{
	this->Destroy();
}

Symbols::Symbols(const char* variable)
{
	this->type = SymbolTypes::VARIABLE_TYPE;
	this->value = Symbols::variable_table.GetIndexByName(variable);
}

Symbols::Symbols(char constant)
{
	this->type = SymbolTypes::CONSTANT_TYPE;
	this->value = constant;
}

Symbols::Symbols(SymbolTypes type, const char* remark)
{
	assert(type == SymbolTypes::REMARK_TYPE || type == SymbolTypes::STRING_TYPE || type == SymbolTypes::ANY_TYPE);
	this->type = type;
	if(type == SymbolTypes::REMARK_TYPE)
    {
        this->value = Symbols::remark_table.GetIndexByName(remark);
    }
	else if (type == SymbolTypes::STRING_TYPE)
    {
        this->s = new shared_ptr<string>(new string(remark));
    }
    else if (type == SymbolTypes::ANY_TYPE)
    {
        this->value = SymbolTypes(remark).type_code;
    }
	else
    {
		throw "unknow symbol type";
	}
}

Symbols::Symbols(const char* type_name, const char* value)
{
    this->type = SymbolTypes(type_name);
    if (this->type < SymbolTypes::USER_DEFINE_TYPE)
    {
        if (this->type == SymbolTypes::ANY_TYPE)    //任意值类型，用来匹配
        {
            this->value = SymbolTypes(value).type_code;
        }
        else if (this->type == SymbolTypes::VOID_TYPE)		//VOID类型，作为空类型
        {
            this->value = 0;
        }
        else if (this->type == SymbolTypes::VARIABLE_TYPE) 	//文法变量类型
        {
            this->value = variable_table.GetIndexByName(value);
        }
        else if (this->type == SymbolTypes::REMARK_TYPE) 		//文法标记类型
        {
            this->value = remark_table.GetIndexByName(value);
        }
        else if (this->type == SymbolTypes::CONSTANT_TYPE || this->type == SymbolTypes::CHAR_TYPE)
        {
            //文法常量类型
            //单个字符类型
            assert(strlen(value) == 1);
            this->c = value[0];
        }
        else if (this->type == SymbolTypes::INTEGER_TYPE) 		//整数类型
        {
            this->i = atoi(value);
        }
        else if (this->type == SymbolTypes::LONG_TYPE) 		//长整数类型
        {
            this->l = atol(value);
        }
        else if (this->type == SymbolTypes::FLOAT_TYPE) 		//浮点数类型
        {
            this->f = atof(value);
        }
        else if (this->type == SymbolTypes::DOUBLE_TYPE) 		//双精度浮点数类型
        {
            this->d = atof(value);
        }
        else if (this->type == SymbolTypes::STRING_TYPE) 		//字符串类型
        {
            this->s = new shared_ptr<string>(new string(value));
        }
        else if (this->type == SymbolTypes::REFERENCE_TYPE) 	//引用類型(指針類型)
        {
            this->reference = nullptr;
        }
        else if (this->type == SymbolTypes::COMPACT_TYPE || this->type == SymbolTypes::S_EXP_TYPE || this->type == SymbolTypes::LIST_TYPE)	//(同之前的内部打包解包类型)
        {
            this->list = nullptr;
        }
        else if (this->type == SymbolTypes::MAP_TYPE)    //字典类型
        {
            this->m = nullptr;
        }
    }
    else
    {
        this->value = value_table.GetIndexByName(value);
    }
}

Symbols::Symbols(SymbolTypes symbol_type, char c)
{
	assert(symbol_type == SymbolTypes::CHAR_TYPE || symbol_type == SymbolTypes::CONSTANT_TYPE);
	
	this->type = symbol_type;
	if (symbol_type == SymbolTypes::CHAR_TYPE)
    {
        this->c = c;
    }
	else if (this->type == SymbolTypes::CONSTANT_TYPE)
    {
        this->value = c;
    }
	else
    {
		throw "unknow symbol type";
	}
}

Symbols::Symbols(int i)
{
	this->type = SymbolTypes::INTEGER_TYPE;
	this->i = i;
}

Symbols::Symbols(long l)
{
	this->type = SymbolTypes::LONG_TYPE;
	this->l = l;
}

Symbols::Symbols(float f)
{
	this->type = SymbolTypes::FLOAT_TYPE;
	this->f = f;
}

Symbols::Symbols(double d)
{
	this->type = SymbolTypes::DOUBLE_TYPE;
	this->d = d;
}

Symbols::Symbols(Symbols* reference)
{
	this->type = SymbolTypes::REFERENCE_TYPE;
	this->reference = reference;
}

Symbols::Symbols(SymbolTypes symbol_type, vector<Symbols> symbols)
{
	assert(symbol_type == SymbolTypes::COMPACT_TYPE || symbol_type == SymbolTypes::S_EXP_TYPE || symbol_type == SymbolTypes::LIST_TYPE);
	this->type = symbol_type;
	this->list = new shared_ptr<vector<Symbols> >(new vector<Symbols>(symbols.size()));
	copy(symbols.begin(), symbols.end(), (*this->list)->begin());
}

Symbols::Symbols(SymbolTypes type)
{
    this->type = type;
    if (type == SymbolTypes::LIST_TYPE || type == SymbolTypes::S_EXP_TYPE || type == SymbolTypes::COMPACT_TYPE)
    {
        this->list = new shared_ptr<vector<Symbols> >(new vector<Symbols>());
    }
    else if (type == SymbolTypes::MAP_TYPE)
    {
        this->m = new shared_ptr<map<string,Symbols> >(new map<string,Symbols>());
    }
    else if (type == SymbolTypes::STRING_TYPE)
    {
        this->s = new shared_ptr<string>(new string());
    }
}

Symbols::Symbols(SymbolTypes type, SymbolTypes value)
{
    assert(type == SymbolTypes::ANY_TYPE);
    this->type = type;
    this->value = value.type_code;
}

bool Symbols::operator== (const Symbols& that) const
{
	if (this->type != that.type) return false;

    if (this->type == SymbolTypes::CHAR_TYPE)
    {
        return (this->c == that.c);
    }
    else if (this->type == SymbolTypes::INTEGER_TYPE)
    {
        return (this->i == that.i);
    }
    else if (this->type == SymbolTypes::LONG_TYPE)
    {
        return (this->l == that.l);
    }
    else if (this->type == SymbolTypes::FLOAT_TYPE)
    {
        return (fabs(this->f - that.f) < 1e-6);
    }
    else if (this->type == SymbolTypes::DOUBLE_TYPE)
    {
        return (fabs(this->d - that.d) < 1e-6);
    }
    else if (this->type == SymbolTypes::COMPACT_TYPE || this->type == SymbolTypes::S_EXP_TYPE || this->type == SymbolTypes::LIST_TYPE)
    {
        return this->GetList() == that.GetList();
    }
    else if (this->type == SymbolTypes::MAP_TYPE)
    {
        return this->GetMap() == that.GetMap();
    }
    else if (this->type == SymbolTypes::STRING_TYPE)
    {
        return *(*this->s) == *(*that.s);
    }
    else
    {
        return (this->value == that.value);
    }
}

bool Symbols::match(const Symbols& that) const
{
    if (*this == Symbols::ANY_SYMBOL || that == Symbols::ANY_SYMBOL) return true;
    if (this->type == SymbolTypes::ANY_TYPE)
    {
        return this->value == that.type.type_code;
    }
    if (that.type == SymbolTypes::ANY_TYPE)
    {
        return that.value == this->type.type_code;
    }
    return *this == that;
}

bool Symbols::operator< (const Symbols& that) const
{
	if (this->type < that.type) return true;
	if (this->type > that.type) return false;

    if (this->type == SymbolTypes::CHAR_TYPE)
    {
        return (this->c < that.c);
    }
    else if (this->type == SymbolTypes::INTEGER_TYPE)
    {
        return (this->i < that.i);
    }
    else if (this->type == SymbolTypes::LONG_TYPE)
    {
        return (this->l < that.l);
    }
    else if (this->type == SymbolTypes::FLOAT_TYPE)
    {
        return (this->f < that.f);
    }
    else if (this->type == SymbolTypes::DOUBLE_TYPE)
    {
        return (this->d < that.d);
    }
    else if (this->type == SymbolTypes::COMPACT_TYPE || this->type == SymbolTypes::S_EXP_TYPE || this->type == SymbolTypes::LIST_TYPE)
    {
        return this->GetList() < that.GetList();
    }
    else if (this->type == SymbolTypes::MAP_TYPE)
    {
        return this->GetMap() < that.GetMap();
    }
    else if (this->type == SymbolTypes::STRING_TYPE)
    {
        return *(*this->s) < *(*that.s);
    }
    else
    {
        return (this->value < that.value);
    }
}

bool operator== (const vector<Symbols>& a, const vector<Symbols>& b)
{
	vector<Symbols>::const_iterator ia = a.begin();
	vector<Symbols>::const_iterator ib = b.begin();
	for(; ia != a.end() && ib != b.end(); ia++, ib++)
	{
		if (!(*ia == *ib)) return false;
	}
	return (ia == a.end() && ib == b.end());	
}

bool operator< (const vector<Symbols>& a, const vector<Symbols>& b)
{
	vector<Symbols>::const_iterator ia = a.begin();
	vector<Symbols>::const_iterator ib = b.begin();
	for(; ia != a.end() && ib != b.end(); ia++, ib++)
	{
		if (*ia < *ib) return true;
		if (!(*ia == *ib)) return false;
	}
	if (ia == a.end() && ib == b.end()) return false;
	if (ia == a.end()) return true;
	if (ib == b.end()) return false;
	return false;	
}

bool operator== (const map<string,Symbols>& a, const map<string,Symbols>& b)
{
	map<string,Symbols>::const_iterator ia = a.begin();
	map<string,Symbols>::const_iterator ib = b.begin();
	for(; ia != a.end() && ib != b.end(); ia++, ib++)
	{
		if (!(ia->first == ib->first && ia->second == ib->second)) return false;
	}
	return (ia == a.end() && ib == b.end());
}

bool operator< (const map<string,Symbols>& a, const map<string,Symbols>& b)
{
	map<string,Symbols>::const_iterator ia = a.begin();
	map<string,Symbols>::const_iterator ib = b.begin();
	for(; ia != a.end() && ib != b.end(); ia++, ib++)
	{
		if (ia->first < ib->first || (ia->first == ib->first && ia->second < ib->second)) return true;
		if (!(ia->first == ib->first && ia->second == ib->second)) return false;
	}
	if (ia == a.end() && ib == b.end()) return false;
	if (ia == a.end()) return true;
	if (ib == b.end()) return false;
	return false;
}

vector<Symbols>& Symbols::GetList()
{
	assert(this->type == SymbolTypes::LIST_TYPE || this->type == SymbolTypes::S_EXP_TYPE || this->type == SymbolTypes::COMPACT_TYPE);
	return(*(*(this->list)));
}

const vector<Symbols>& Symbols::GetList() const
{
    assert(this->type == SymbolTypes::LIST_TYPE || this->type == SymbolTypes::S_EXP_TYPE || this->type == SymbolTypes::COMPACT_TYPE);
	return(*(*(this->list)));
}

map<string, Symbols>& Symbols::GetMap()
{
	assert(this->type == SymbolTypes::MAP_TYPE);
	return(*(*(this->m)));
}

const map<string, Symbols>& Symbols::GetMap() const
{
    assert(this->type == SymbolTypes::MAP_TYPE);
	return(*(*(this->m)));
}

bool Symbols::IsVariable() const
{
	return this->type == SymbolTypes::VARIABLE_TYPE;
}

bool Symbols::IsConstant() const
{
	return this->type == SymbolTypes::CONSTANT_TYPE;
}

bool Symbols::IsRemark() const
{
	return this->type == SymbolTypes::REMARK_TYPE;
}

string Symbols::ToString() const
{
	char tmp[2] = "";
	string result = "";

	if (this->type == SymbolTypes::VARIABLE_TYPE)
    {
        return (Symbols::variable_table.GetNameByIndex(this->value));
    }
	else if (this->type == SymbolTypes::REMARK_TYPE)
    {
        return (Symbols::remark_table.GetNameByIndex(this->value));
    }
	else if (this->type == SymbolTypes::CONSTANT_TYPE)
    {
        tmp[0] = char(this->value);
        return string(tmp);
    }
	else if (this->type == SymbolTypes::CHAR_TYPE)
    {
        tmp[0] = char(this->c);
        return string(tmp);
    }
	else if (this->type == SymbolTypes::INTEGER_TYPE)
    {
        Int2String(this->i, result);
        return result;
    }
	else if (this->type == SymbolTypes::LONG_TYPE)
    {
        Long2String(this->l, result);
        return result;
    }
	else if (this->type == SymbolTypes::FLOAT_TYPE)
    {
        Float2String(this->f, result);
        return result;
    }
	else if (this->type == SymbolTypes::DOUBLE_TYPE)
    {
        Double2String(this->d, result);
        return result;
    }
	else if (this->type == SymbolTypes::REFERENCE_TYPE)
    {
        char buffer[80];
        snprintf(buffer, sizeof(buffer)-1, "%p", this->reference);
        buffer[sizeof(buffer)-1] = 0;
        return string(buffer);
    }
	else if (this->type == SymbolTypes::STRING_TYPE)
    {
        return *(*this->s);
    }
	else if (this->type == SymbolTypes::COMPACT_TYPE)
    {
        const vector<Symbols>& l = this->GetList();
        if(!l.empty())
        {
            for(vector<Symbols>::const_iterator i = l.begin(); i != l.end(); ++i)
            {
                result += i->ToString();
            }
        }
        return result;
    }
	else if (this->type == SymbolTypes::S_EXP_TYPE)
    {
        result += "(";
        const vector<Symbols>& l = this->GetList();
        if(!l.empty())
        {
            vector<Symbols>::const_iterator i = l.begin();
            result += i->ToString();
            for(++i; i != l.end(); ++i)
            {
                result += ",";
                result += i->ToString();
            }
        }
        result +=")";
        return result;
    }
	else if (this->type == SymbolTypes::LIST_TYPE)
    {
        result += "[";
        const vector<Symbols>& l = this->GetList();
        if(!l.empty())
        {
            vector<Symbols>::const_iterator i = l.begin();
            result += i->ToString();
            for(++i; i != l.end(); ++i)
            {
                result += ",";
                result += i->ToString();
            }
        }
        result +="]";
        return result;
    }
	else if (this->type == SymbolTypes::MAP_TYPE)
    {
        result += "{";
        const map<string, Symbols>& l = this->GetMap();
        if(!l.empty())
        {
            map<string, Symbols>::const_iterator i = l.begin();
            result +=  i->first + "=>" + i->second.ToString();
            for(++i; i != l.end(); ++i)
            {
                result += ",";
                result +=  i->first + "=>" + i->second.ToString();
            }
        }
        result +="}";
        return result;
    }
    else if (*this == Symbols::ANY_SYMBOL)
    {
	return "*";
    }
    else if (this->type == SymbolTypes::ANY_TYPE)
    {
        return (SymbolTypes::type_table.GetNameByIndex(this->value));
    }
	else if (!(this->type < SymbolTypes::USER_DEFINE_TYPE))
    {
        return (Symbols::value_table.GetNameByIndex(this->value));
	}
	return "";
}

void Symbols::Display(ostream& o) const
{
	o<<this->ToString();
}

void Symbols::Dump(ostream& o) const
{
#ifdef DEBUG
	o << "{";
    o << this->type.ToString();

	o << ",";
#endif

	if(this->type == SymbolTypes::CONSTANT_TYPE)
    {
        switch (this->value)
        {
            case '"':
                o << "\\\"";
                break;
            case '\\':
                o << "\\\\";
                break;
            case '\t':
                o << "\\t";
                break;
            case '\r':
                o << "\\r";
                break;
            case '\n':
                o << "\\n";
                break;
            default:
                o << (char) this->value;
                break;
        }
    }
    else
    {
		o<<this->ToString();
	}

#ifdef DEBUG
	o << "}";
#endif
}

void Symbols::Save(ostream& o) const
{
    assert(!(this->type == SymbolTypes::COMPACT_TYPE || this->type == SymbolTypes::S_EXP_TYPE || this->type == SymbolTypes::LIST_TYPE || this->type == SymbolTypes::MAP_TYPE));
    o.write(reinterpret_cast<const char *>(&this->type), sizeof(this->type));

    if (this->type == SymbolTypes::STRING_TYPE)
    {
        int length = (**this->s).size();
        o.write(reinterpret_cast<const char *>(&length), sizeof(length));
        o.write((**this->s).c_str(), length);
    }
    else
    {
        o.write(reinterpret_cast<const char *>(&this->l), sizeof(this->l));
    }
}

void Symbols::Load(istream& i)
{
    i.read(reinterpret_cast<char *>(&this->type), sizeof(this->type));
    assert(!(this->type == SymbolTypes::COMPACT_TYPE || this->type == SymbolTypes::S_EXP_TYPE || this->type == SymbolTypes::LIST_TYPE || this->type == SymbolTypes::MAP_TYPE));
    if (this->type == SymbolTypes::STRING_TYPE)
    {
        int length = 0;
        char buffer[1024] = {0};
        i.read(reinterpret_cast<char*>(&length), sizeof(length));
        assert(length < 1024);
        i.read(buffer, length);
        buffer[length] = 0;
        this->s = new shared_ptr<string>(new string(buffer, 0, length));
    }
    else
    {
        i.read(reinterpret_cast<char *>(&this->l), sizeof(this->l));
    }
}

void Symbols::Save()
{
    string symbol_table_file_name = CompilerManager::GetSymbolTableFileName();
    ofstream output_stream(symbol_table_file_name);
    SymbolTypes::Save(output_stream);
    Symbols::variable_table.Save(output_stream);
    Symbols::remark_table.Save(output_stream);
    Symbols::value_table.Save(output_stream);
    output_stream.close();
}

void Symbols::Load()
{
    string symbol_table_file_name = CompilerManager::GetSymbolTableFileName();
    if (access(symbol_table_file_name.c_str(),R_OK) == 0)
    {
        ifstream input_stream(symbol_table_file_name);
        SymbolTypes::Load(input_stream);
        Symbols::variable_table.Load(input_stream);
        Symbols::remark_table.Load(input_stream);
        Symbols::value_table.Load(input_stream);
        input_stream.close();
    }
}

istream& operator>> (istream&ins, vector<Symbols>& symbols)
{
	//symbols.clear();

	char c=ins.get();
	if(!ins.eof())
	{
		do
		{
			symbols.push_back(Symbols(c));
			c=ins.get();
		}while(!ins.eof());
	}

	return ins;
}

ostream& operator<< (ostream& o, const Symbols& symbol)
{
//#define DEBUG
#ifdef DEBUG
	symbol.Dump(o);
#else
	symbol.Display(o);
#endif
	return o;
}

ostream& operator<< (ostream& o, const vector<Symbols>& symbols)
{
	for(vector<Symbols>::const_iterator i = symbols.begin(); i != symbols.end(); ++i)
	{
		o<<*i;
	}
	return o;
}

int Split(const vector<Symbols>&symbols, Symbols seperator, vector< vector<Symbols> >& fields)
{
	fields.clear();
	if(symbols.empty()) return 0;

	vector<Symbols> field;
	for(vector<Symbols>::const_iterator i = symbols.begin(); i != symbols.end(); ++i)
	{
		if(*i == seperator)
		{
			fields.push_back(field);
			field.clear();
		}
		else
		{
			field.push_back(*i);
		}
	}
	fields.push_back(field);
	return fields.size();
}

int SplitParameters(const vector<Symbols>&symbols, vector< vector<Symbols> >& fields)
{
	return SplitParameters(symbols.begin(), symbols.end(), fields);
}

int SplitParameters(vector<Symbols>::const_iterator begin, vector<Symbols>::const_iterator end, vector< vector<Symbols> >& fields)
{
	fields.clear();
	if(begin>=end) return 0;

	vector<Symbols> field;
	int depth = 0;
	for(vector<Symbols>::const_iterator i = begin; i != end; ++i)
	{
		if(*i == Symbols::SEPERATOR && depth == 0)
		{
			fields.push_back(field);
			field.clear();
		}
		else
		{
			if(*i == Symbols::LEFT_QUOTE)
			{
				depth++;
			}
			else if(*i == Symbols::RIGHT_QUOTE)
			{
				depth--;
			}
			field.push_back(*i);
		}
	}
	fields.push_back(field);
	return fields.size();
}

int SplitSList(const vector<Symbols>&symbols, vector< vector<Symbols> >& fields)
{
	if(symbols.empty()) return 0;
	if(symbols.front() == Symbols::LEFT_QUOTE && symbols.back() == Symbols::RIGHT_QUOTE)
	{
		return SplitParameters(symbols.begin()+1, symbols.end()-1, fields);
	}
	else
	{
		return -1;
	}
}

//分解表达式为符号列表
int SplitExpression(const vector<Symbols>&symbols, vector< vector<Symbols> >& fields)
{
	fields.clear();
	if(symbols.empty()) return 0;

	vector<Symbols> field;
	int depth = 0;
	for(vector<Symbols>::const_iterator i = symbols.begin(); i != symbols.end(); ++i)
	{
		field.push_back(*i);

		if(*i == Symbols::LEFT_QUOTE)
		{
			depth++;
		}
		else if(*i == Symbols::RIGHT_QUOTE)
		{
			depth--;
		}

		if(depth == 0)
		{
			fields.push_back(field);
			field.clear();
		}
	}

	return fields.size();
}

void ComposeSList(vector<vector<Symbols> >::const_iterator begin, vector<vector<Symbols> >::const_iterator end, vector<Symbols>& slist)
{
	slist.push_back(Symbols::LEFT_QUOTE);
	for(vector<vector<Symbols> >::const_iterator i = begin; i != end; ++i)
	{
		slist += *i;
		slist.push_back(Symbols::SEPERATOR);
	}
	if(slist.back() == Symbols::SEPERATOR) slist.pop_back();
	slist.push_back(Symbols::RIGHT_QUOTE);
}

vector<Symbols>& operator+= (vector<Symbols>& a, const vector<Symbols>& b)
{
	for(vector<Symbols>::const_iterator i = b.begin(); i != b.end(); ++i)
	{
		a.push_back(*i);
	}
	return a;
}

std::vector<Symbols>& operator+= (std::vector<Symbols>& a, const std::string& b)
{
	for(string::const_iterator i = b.begin(); i != b.end(); ++i)
	{
		a.push_back(*i);
	}
	return a;
}

const std::string& ToString (std::string& str, const std::vector<Symbols>& symbols)
{
	str.clear();
	for(std::vector<Symbols>::const_iterator i = symbols.begin(); i != symbols.end(); ++i)
	{
		str.push_back(char(i->value));
	}
	return str;
}

void AssertSymbolsType(vector<Symbols> symbols, SymbolTypes symbol_type)
{
	for(vector<Symbols>::const_iterator i = symbols.begin(); i != symbols.end(); i++)
	{
		assert(i->type == symbol_type);
	}
}

bool CompactSExpression(const std::vector<Symbols>& input_symbols, Symbols& compacted_input_symbols)
{
	assert(compacted_input_symbols.type == SymbolTypes::COMPACT_TYPE);

	vector<Symbols*> current_compected_symbol_stack;
	Symbols* current_compected_symbol = &compacted_input_symbols;
	int deepth = 0;

	for (std::vector<Symbols>::const_iterator i = input_symbols.begin(); i != input_symbols.end(); i++) 
	{
		if (*i == Symbols::LEFT_QUOTE)
		{
			deepth++;
			current_compected_symbol_stack.push_back(current_compected_symbol);
			current_compected_symbol = new Symbols(SymbolTypes::S_EXP_TYPE);
			current_compected_symbol_stack.push_back(current_compected_symbol);
			current_compected_symbol = new Symbols(SymbolTypes::COMPACT_TYPE);
		}
		else if (*i == Symbols::RIGHT_QUOTE)
		{
			deepth--;
			if (deepth < 0) return false;
			
			Symbols* parent_compect_symbol = current_compected_symbol_stack.back();
			assert(parent_compect_symbol->type == SymbolTypes::S_EXP_TYPE);

			if (current_compected_symbol->GetList().size() == 1)
			{
				parent_compect_symbol->GetList().push_back(current_compected_symbol->GetList()[0]);
			}
			else
			{
				if (!current_compected_symbol->GetList().empty() || !parent_compect_symbol->GetList().empty())
				{
					parent_compect_symbol->GetList().push_back(*current_compected_symbol);
				}
			}
			delete current_compected_symbol;
			current_compected_symbol = parent_compect_symbol;
			current_compected_symbol_stack.pop_back();

			parent_compect_symbol = current_compected_symbol_stack.back();
			assert(parent_compect_symbol->type == SymbolTypes::COMPACT_TYPE);
			parent_compect_symbol->GetList().push_back(*current_compected_symbol);
			delete current_compected_symbol;
			current_compected_symbol = parent_compect_symbol;
			current_compected_symbol_stack.pop_back();
		}
		else if (*i == Symbols::SEPERATOR)
		{
			if (deepth == 0) return false;

			Symbols* parent_compect_symbol = current_compected_symbol_stack.back();
			assert(parent_compect_symbol->type == SymbolTypes::S_EXP_TYPE);

			if (current_compected_symbol->GetList().size() == 1)
			{
				parent_compect_symbol->GetList().push_back(current_compected_symbol->GetList()[0]);
			}
			else
			{
				parent_compect_symbol->GetList().push_back(*current_compected_symbol);
			}
			current_compected_symbol->GetList().clear();
		}
		else
		{
			assert(current_compected_symbol->type == SymbolTypes::COMPACT_TYPE);
			current_compected_symbol->GetList().push_back(*i);	
		}
	}

	return true;
}
